import {computed, getCurrentInstance, inject, ref, unref} from 'vue';

export const defaultNamespace = 'hhd';
const statePrefix = 'is-';

const _bem = (
  namespace: string,
  block: string,
  blockSuffix: string,
  element: string,
  modifier: string
) => {
  let cls = `${namespace}-${block}`;
  if (blockSuffix) {
    cls += `-${blockSuffix}`;
  }
  if (element) {
    cls += `__${element}`;
  }
  if (modifier) {
    cls += `--${modifier}`;
  }
  return cls;
};

export const namespaceContextKey =
  Symbol('namespaceContextKey');

export const useGetDerivedNamespace = (
  namespaceOverrides?: string
) => {
  const derivedNamespace =
    namespaceOverrides ||
    (getCurrentInstance()
      ? inject(namespaceContextKey, ref(defaultNamespace))
      : ref(defaultNamespace));
  const namespace = computed(() => {
    return unref(derivedNamespace) || defaultNamespace;
  });
  return namespace;
};

export const useNamespace = (
  block: string,
  namespaceOverrides?: string
) => {
  const namespace = useGetDerivedNamespace(namespaceOverrides);
  const b = (blockSuffix = '') =>
    _bem(namespace.value, block, blockSuffix, '', '');
  const e = (element: string) =>
    element ? _bem(namespace.value, block, '', element, '') : '';
  const m = (modifier: string) =>
    modifier ? _bem(namespace.value, block, '', '', modifier) : '';
  const be = (blockSuffix: string, element: string) =>
    blockSuffix && element
      ? _bem(namespace.value, block, blockSuffix, element, '')
      : '';
  const em = (element: string, modifier: string) =>
    element && modifier
      ? _bem(namespace.value, block, '', element, modifier)
      : '';
  const bm = (blockSuffix: string, modifier: string) =>
    blockSuffix && modifier
      ? _bem(namespace.value, block, blockSuffix, '', modifier)
      : '';
  const bem = (blockSuffix: string, element: string, modifier: string) =>
    blockSuffix && element && modifier
      ? _bem(namespace.value, block, blockSuffix, element, modifier)
      : '';
  const is = (name: string, state: boolean) => {
    return name && state ? `${statePrefix}${name}` : ''
  };


  const cssVarName = (name: string) => `--${namespace.value}-${name}`;
  const cssVarBlockName = (name: string) =>
    `--${namespace.value}-${block}-${name}`;

  return {
    namespace,
    b,
    e,
    m,
    be,
    em,
    bm,
    bem,
    is,
    // css
    cssVarName,
    cssVarBlockName,
  };
};

